﻿using APP.BaseClass;
using APP.IO;
using OpenCvSharp;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace APP.OpenCV
{

    public class ChipMatchItemMode
    {
        public string ImagePath { get; set; }
        public int Number { get; set; }
        public Point[][] Contours { get; set; }

        public bool IsBombo { get; set; }
    }

    /// <summary>
    /// 利用轮廓相似度 MatchShapes https://blog.csdn.net/Kevin_Sun777/article/details/111395898
    /// </summary>
    public class OpenCVOCRHelper3
    {

        public void Init()
        {
            var folder = @"C:\repo\Play\minesweeper-auto-scan-demo.git\MinesweeperAutoScanDemo\APP.OpenCV\Resources\";
            //var folder = @"D:\mypo\MinesweeperAutoScanDemo\MinesweeperAutoScanDemo\APP.OpenCV\Resources\";

            //var assName= System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;
            for (int i = 1; i < 5; i++)
            {
                ChipMatchItemMode item = new ChipMatchItemMode();
                var imagePath = folder + $"{i}.jpg";
                item.ImagePath = imagePath;
                var result = GetContours(imagePath);
                item.Contours = result.Data;
                item.Number = i;
                OriginData.Add(item);
            }

            //{
            //    ChipMatchItemMode item = new ChipMatchItemMode();
            //    var imagePath = folder + $"Bombo.jpg";
            //    item.ImagePath = imagePath;
            //    var result = GetContours(imagePath);
            //    item.Contours = result.Data;
            //    item.Number = -1;
            //    item.IsBombo = true;
            //    OriginData.Add(item);
            //}
        }

        static int thresh_Min = 130;
        static int thresh_Max = 255;
        static int Contours_Min = 80;
        static int Contours_Max = 400;

        List<ChipMatchItemMode> OriginData = new List<ChipMatchItemMode>();


        public FeedBack<int> MatchNumber(string picturePath)
        {
            FeedBack<int> result = new FeedBack<int>();
            var back = GetContours(picturePath);
            if (!back.Success || back.Data.Length <= 0)
            {
                return result;
            }
            if (back.Data.First().Count(x => x.Y == 0 || x.X == 0) > 30)
            {
                return result;
            }
            List<object> rateList = new List<object>();
            var matchList = OriginData.Select(x => new
            {
                MatchItem = x,
                rate = Cv2.MatchShapes(back.Data.First(), x.Contours.First(), ShapeMatchModes.I1)
            }).ToList();
            if (matchList.Count <= 0)
            {
                return result;
            }
            if (matchList.Where(x => x.rate < 0.1).Count() > 0)
            {
                var minRate = matchList.Min(x => x.rate);
                var goodMatch = matchList.First(x => x.rate == minRate);
                result.Success = true;
                result.Data = goodMatch.MatchItem.Number;
            }


            return result;
        }


        public FeedBack<Point[][]> GetContours(string picturePath)
        {
            FeedBack<Point[][]> result = new FeedBack<Point[][]>();

            Mat srcImage = Cv2.ImRead(picturePath);
            Mat grayImage = new Mat();
            Mat Image = new Mat();
            Mat dstImage = new Mat();
            srcImage.CopyTo(dstImage);
            Cv2.CvtColor(srcImage, grayImage, ColorConversionCodes.BGR2GRAY);
            Cv2.Threshold(grayImage, Image, thresh_Min, thresh_Max, ThresholdTypes.BinaryInv);

            Cv2.FindContours(Image, out Point[][] contours, out HierarchyIndex[] hierarchy, RetrievalModes.External, ContourApproximationModes.ApproxNone);
            if (contours.Length > 0)
            {
                foreach (var item in contours)
                {
                    if (item.Length > Contours_Min)
                    {
                        result.Success = true;
                        result.Data = contours;
                    }
                }
                //DebugOutPutContourt(picturePath, Image, contours);
            }
            return result;
        }

        public void DebugOutPutContourt(string picturePath, Mat Image, Point[][] contours)
        {
            for (int itemIndex = 0; itemIndex < contours.Length; itemIndex++)
            {
                var item = contours[itemIndex];
                var itemRect = Cv2.BoundingRect(item);
                Mat resultImage = new Mat(Image, itemRect);
                //var newMap = resultImage;

                var folder = PathHelper.GetPath(FolderType.Temp, "ImageContour");
                var fileName = Path.GetFileNameWithoutExtension(picturePath);
                var fileExtension = Path.GetExtension(picturePath);
                var savePath = Path.Combine(folder, fileName + itemIndex + fileExtension);
                Cv2.DrawContours(resultImage, contours, itemIndex, new Scalar(255, 0, 0), 2);
                Cv2.ImWrite(savePath, resultImage);
            }
        }


    }
}
